package com.small.nacos.client.config.impl;

import com.small.nacos.api.common.ApiConstants;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.utils.StringUtils;
import com.small.nacos.client.config.filter.impl.ConfigResponse;
import com.small.nacos.client.config.http.HttpAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE;
import static com.alibaba.nacos.api.common.Constants.ENCRYPTED_DATA_KEY;

/**
 * @Author zhoujin
 * @Date 2022/11/18 17:25
 */
public class ClientWorker {

    private final static Logger LOGGER = LoggerFactory.getLogger(ClientWorker.class);

    private final HttpAgent agent;

    private final Properties properties;

    public ClientWorker(HttpAgent agent, Properties properties) {
        this.agent = agent;
        this.properties = properties;
    }

    public ConfigResponse getServerConfig(String dataId, String group, String tenant, long readTimeout) throws NacosException {
        ConfigResponse configResponse = new ConfigResponse();
        if (StringUtils.isBlank(group)) {
            group = ApiConstants.DEFAULT_GROUP;
        }

        HttpRestResult<String> result = null;
        try {
            Map<String, String> params = new HashMap<String, String>(3);
            if (StringUtils.isBlank(tenant)) {
                params.put("dataId", dataId);
                params.put("group", group);
            } else {
                params.put("dataId", dataId);
                params.put("group", group);
                params.put("tenant", tenant);
            }
            result = agent.httpGet(ApiConstants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
        } catch (Exception ex) {
            String message = String
                    .format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s",
                            agent.getName(), dataId, group, tenant);
            LOGGER.error(message, ex);
            throw new NacosException(NacosException.SERVER_ERROR, ex);
        }

        switch (result.getCode()){
            //请求成功
            case HttpURLConnection.HTTP_OK:
                //保存配置文件内容
                LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.getData());
                configResponse.setContent(result.getData());
                //设置配置文件格式
                String configType;
                if (result.getHeader().getValue(CONFIG_TYPE) != null) {
                    configType = result.getHeader().getValue(CONFIG_TYPE);
                } else {
                    configType = ConfigType.TEXT.getType();
                }
                configResponse.setConfigType(configType);
                //获取配置文件对应的秘钥
                String encryptedDataKey = result.getHeader().getValue(ENCRYPTED_DATA_KEY);
                //保存快照配置文件秘钥
                LocalEncryptedDataKeyProcessor
                        .saveEncryptDataKeySnapshot(agent.getName(), dataId, group, tenant, encryptedDataKey);
                configResponse.setEncryptedDataKey(encryptedDataKey);
                return configResponse;
            //没有找到配置类
            case HttpURLConnection.HTTP_NOT_FOUND:
                LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
                LocalEncryptedDataKeyProcessor.saveEncryptDataKeySnapshot(agent.getName(), dataId, group, tenant, null);
                return configResponse;
            //连接失败,未获取到锁
            case HttpURLConnection.HTTP_CONFLICT: {
                LOGGER.error(
                        "[{}] [sub-server-error] get server config being modified concurrently, dataId={}, group={}, "
                                + "tenant={}", agent.getName(), dataId, group, tenant);
                throw new NacosException(NacosException.CONFLICT,
                        "data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
            }
            //连接被拒绝
            case HttpURLConnection.HTTP_FORBIDDEN: {
                LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(),
                        dataId, group, tenant);
                throw new NacosException(result.getCode(), result.getMessage());
            }
            //默认错误
            default: {
                LOGGER.error("[{}] [sub-server-error]  dataId={}, group={}, tenant={}, code={}", agent.getName(),
                        dataId, group, tenant, result.getCode());
                throw new NacosException(result.getCode(),
                        "http error, code=" + result.getCode() + ",dataId=" + dataId + ",group=" + group + ",tenant="
                                + tenant);
            }

        }
    }
}
